// 模拟实现一个call
Function.prototype.call2 = function (context) {
  var context = context || window
  context.fn = this
  let args = [...arguments].splice(1)
  var res = context.fn(...args)
  delete context.fn
  return res
}

// 模拟实现一个apply
Function.prototype.apply2 = function (context, arr) {
  var context = context || window
  context.fn = this
  var res
  if (!arr) {
    res = context.fn()
  } else {
    if (!(arr instanceof Array)) throw new Error("params must be array")
    res = context.fn(...arr)
  }
  delete context.fn
  return res
}

// 模拟实现一个bind
Function.prototype.bind2 = function (context, ...rest) {
  if (typeof this !== 'function') throw new TypeError('invalid invoked!');
  var self = this
  return function F (...args) {
    if (this instanceof F) {
      return new self(...rest, ...args)
    }
    return self.apply(context, [...rest, ...args])
  }
}